package com.ruoyi.door.controller.admin.adsl;

import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.excel.EasyExcel;
import com.ruoyi.door.controller.admin.adsl.vo.DoorAdslImportRespVO;
import lombok.extern.slf4j.Slf4j;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.easy.query.api.proxy.base.ClassProxy;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SysDeptUtil;
import com.ruoyi.door.controller.admin.adsl.vo.DoorAdslChangeGuidReqVO;
import com.ruoyi.door.controller.admin.adsl.vo.DoorAdslImportVO;
import com.ruoyi.door.controller.admin.adsl.vo.DoorAdslPageReqVO;
import com.ruoyi.door.controller.admin.adsl.vo.DoorAdslRespVO;
import com.ruoyi.door.controller.admin.adsl.vo.proxy.DoorAdslRespVOProxy;
import com.ruoyi.door.domain.DoorGuidLog;
import com.ruoyi.door.domain.DoorHouse;
import com.ruoyi.door.domain.DoorLandlord;
import com.ruoyi.door.service.DoorAdslService;
import com.ruoyi.system.mapper.SysDeptMapper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.enums.BusinessType;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.constant.HttpStatus;
import com.easy.query.core.api.pagination.EasyPageResult;
import com.easy.query.api.proxy.client.EasyEntityQuery;
import com.easy.query.api.proxy.entity.select.EntityQueryable;
import com.ruoyi.door.domain.proxy.DoorAdslProxy;
import com.ruoyi.door.domain.DoorAdsl;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;

/**
 * 宽带Controller
 *
 * @author ruoyi
 * @date 2025-06-21
 */
@Api(value = "宽带管理", tags = "宽带管理")
@RestController
@RequestMapping("/door/adsl")
@Slf4j
public class DoorAdslController extends BaseController {
    @Autowired
    private EasyEntityQuery easyEntityQuery;
    @Autowired
    private SysDeptMapper sysDeptMapper;
    @Autowired
    private DoorAdslService doorAdslService;
    @Autowired
    private RedisCache redisCache;
    private EntityQueryable<DoorAdslRespVOProxy, DoorAdslRespVO> buildQuery(DoorAdslPageReqVO doorAdsl) {


        EntityQueryable<DoorAdslRespVOProxy, DoorAdslRespVO> select = easyEntityQuery.queryable(DoorAdsl.class)
                .leftJoin(DoorHouse.class, (d, h) -> d.houseId().eq(h.id()))
                .leftJoin(SysUser.class, (d, h, u) -> u.userId().eq(h.landlordId()))
                .leftJoin(SysDept.class, (d, h, u, d1) -> h.country().eq(d1.deptId()))
                .leftJoin(SysDept.class, (d, h, u, d1, d2) -> h.province().eq(d2.deptId()))
                .leftJoin(SysDept.class, (d, h, u, d1, d2, d3) -> h.city().eq(d3.deptId()))
                .leftJoin(SysDept.class, (d, h, u, d1, d2, d3, d4) -> h.district().eq(d4.deptId()))
                .leftJoin(SysDept.class, (d, h, u, d1, d2, d3, d4, d5) -> h.street().eq(d5.deptId()))
                .leftJoin(SysDept.class, (d, h, u, d1, d2, d3, d4, d5, d6) -> h.village().eq(d6.deptId()))
                .where((d, h, u, d1, d2, d3, d4, d5, d6) -> {
                    if (doorAdsl.getId() != null) {
                        d.id().eq(doorAdsl.getId());
                    }
                    if (doorAdsl.getCountry() != null) {
                        h.country().eq(doorAdsl.getCountry());
                    }
                    if (doorAdsl.getCity() != null) {
                        h.city().eq(doorAdsl.getCity());
                    }
                    if (doorAdsl.getProvince() != null) {
                        h.province().eq(doorAdsl.getProvince());
                    }
                    if (doorAdsl.getDistrict() != null) {
                        h.district().eq(doorAdsl.getDistrict());
                    }
                    if (doorAdsl.getVillage() != null) {
                        h.village().eq(doorAdsl.getVillage());
                    }
                    if (doorAdsl.getStreet() != null) {
                        h.street().eq(doorAdsl.getStreet());
                    }
                    if (doorAdsl.getHouseId() != null) {
                        d.houseId().eq(doorAdsl.getHouseId());
                    }
                    if (doorAdsl.getDeptId() != null) {
                        h.deptId().eq(doorAdsl.getDeptId());
                    }
                    if (StringUtils.isNotBlank(doorAdsl.getKeyword())) {
                       d.or(()->{
                          d.jzxm().like(doorAdsl.getKeyword());
                           h.address().like(doorAdsl.getKeyword());
                           d.zjlxdh().like(doorAdsl.getKeyword());
                       });
                    }
                    if (StringUtils.isNotBlank(doorAdsl.getAddress())) {
                        h.address().like(doorAdsl.getAddress());
                    }
                    if (StringUtils.isNotBlank(doorAdsl.getKdzh())) {
                        d.kdzh().like(doorAdsl.getKdzh());
                    }
                    if (StringUtils.isNotBlank(doorAdsl.getSgk())) {
                        d.sgk().like(doorAdsl.getSgk());
                    }
                    if (StringUtils.isNotBlank(doorAdsl.getSfys())) {
                        d.sfys().like(doorAdsl.getSfys());
                    }
                    if (StringUtils.isNotBlank(doorAdsl.getSfzbmq())) {
                        d.sfzbmq().like(doorAdsl.getSfzbmq());
                    }
                    if (StringUtils.isNotBlank(doorAdsl.getZsry())) {
                        d.zsry().like(doorAdsl.getZsry());
                    }
                    if (StringUtils.isNotBlank(doorAdsl.getKdmm())) {
                        d.kdmm().like(doorAdsl.getKdmm());
                    }
                    if (StringUtils.isNotBlank(doorAdsl.getSfzs())) {
                        d.sfzs().like(doorAdsl.getSfzs());
                    }
                    if (StringUtils.isNotBlank(doorAdsl.getMjbm())) {
                        d.mjbm().like(doorAdsl.getMjbm());
                    }
                    if (StringUtils.isNotBlank(doorAdsl.getFilePath())) {
                        d.filePath().eq(doorAdsl.getFilePath());
                    }
                    if (StrUtil.isNotEmpty(doorAdsl.getJzxm())) {
                        d.jzxm().like(doorAdsl.getJzxm());
                    }
                    if (StrUtil.isNotEmpty(doorAdsl.getLandlordName())) {
                        u.nickName().like(doorAdsl.getLandlordName());
                    }
                    if (StrUtil.isNotEmpty(doorAdsl.getLandlordPhone())) {
                        u.phonenumber().like(doorAdsl.getLandlordPhone());
                    }
                    if (ObjectUtil.isNotNull(doorAdsl.getLandlordId())) {
                        u.userId().eq(doorAdsl.getLandlordId());
                    }
                }).orderBy((d1, h, u, s4, s5, s6, s7, s8, s9) -> d1.id().desc())
                .select((d1, h, u, s4, s5, s6, s7, s8, s9) -> {
                    DoorAdslRespVOProxy r = new DoorAdslRespVOProxy();//在BanCardVO上添加@EntityProxy注解build时会生成对应的Proxy对象
                    r.selectAll(d1);
                    r.door().set(h.door());
                    r.monthPrice().set(h.monthPrice());
                    r.startDate().set(h.startDate());
                    r.endDate().set(h.endDate());
                    r.countryName().set(s4.deptName());
                    r.provinceName().set(s5.deptName());
                    r.cityName().set(s6.deptName());
                    r.districtName().set(s7.deptName());
                    r.streetName().set(s8.deptName());
                    r.villageName().set(s9.deptName());
                    r.address().set(h.address());
                    r.landlordName().set(u.nickName());
                    r.landlordPhone().set(u.phonenumber());
                    return r;
                });
         return select;
    }

    /**
     * 查询宽带列表
     */
    @ApiOperation("查询宽带列表")
    @GetMapping("/list")
    @Anonymous
    public TableDataInfo list(DoorAdslPageReqVO doorAdsl) {
        //2、资料管理，需要将我们之前给的表里面的所有信息都展示出来，可导入导出，可搜索；搜索屋主名，手机号，地址，门禁编码;
        EasyPageResult<DoorAdslRespVO> pageResult = buildQuery(doorAdsl)

                .toPageResult(TableSupport.buildPageRequest().getPageNum(),
                        TableSupport.buildPageRequest().getPageSize());
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        rspData.setRows(pageResult.getData());
        rspData.setTotal(pageResult.getTotal());
        return rspData;
    }

    /**
     * 导出宽带列表
     */
    @ApiOperation("导出宽带列表")
    @Log(title = "宽带", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, DoorAdslPageReqVO doorAdsl) {
        List<DoorAdslRespVO> list = buildQuery(doorAdsl).toList();
        List<DoorAdslImportVO> adslImportVOS = BeanUtil.copyToList(list, DoorAdslImportVO.class);
        ExcelUtil<DoorAdslImportVO> util = new ExcelUtil<DoorAdslImportVO>(DoorAdslImportVO.class);
        util.exportExcel(response, adslImportVOS, "宽带数据");
    }

    /**
     * 获取宽带详细信息
     */
    @ApiOperation("获取宽带详细信息")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(easyEntityQuery.queryable(DoorAdsl.class).where(x -> x.id().eq(id))
                .firstOrNull());
    }

    /**
     * 新增宽带
     */
    @ApiOperation("新增宽带")
    @Log(title = "宽带", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody DoorAdsl doorAdsl) {
        long rows = easyEntityQuery.insertable(doorAdsl).executeRows();
        return toAjax(rows > 0);
    }

    /**
     * 修改宽带
     */
    @ApiOperation("修改宽带")
    @Log(title = "宽带", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody DoorAdsl doorAdsl) {
        return toAjax(easyEntityQuery.updatable(doorAdsl).executeRows() > 0);
    }

    /**
     * 删除宽带
     */
    @ApiOperation("删除宽带")
    @Log(title = "宽带", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        long rows = easyEntityQuery.deletable(DoorAdsl.class)
                .disableLogicDelete()//禁用逻辑删除,使用物理删除
                .allowDeleteStatement(true)//如果不允
                .where(x -> x.id().in(ids))
                .executeRows();
        return toAjax(rows > 0);
    }

    @GetMapping("/importTemplate")
    @ApiOperation("资料导入模板")
    @Anonymous
    public void importTemplate(HttpServletResponse response) throws IOException {
        String fileName = "资料导入模板" + DateUtils.getTime() + ".xlsx";
        String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
        InputStream stream = ResourceUtil.getStream("classpath:" + "template/资料导入模板.xlsx");
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedFileName + "\"; filename*=UTF-8''" + encodedFileName);
        ServletOutputStream out = response.getOutputStream();
        byte[] buffer = new byte[1024];
        int bytesRead;
        while ((bytesRead = stream.read(buffer)) != -1) {
            out.write(buffer, 0, bytesRead);
        }
        out.flush();
        out.close();
    }

    @PostMapping("/importData")
    @ApiOperation("资料导入")
    @Log(title = "资料管理", businessType = BusinessType.IMPORT)
    public void importData(MultipartFile file, boolean updateSupport, HttpServletResponse response) throws Exception {
        String uuid = IdUtil.fastUUID();
        Map<String, Object> result = doorAdslService.importData(file, uuid);
        
        @SuppressWarnings("unchecked")
        List<DoorAdslImportRespVO> failureList = (List<DoorAdslImportRespVO>) result.get("failureList");
        
        // 设置Excel响应头
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        
        String fileName = java.net.URLEncoder.encode("资料导入结果_" + DateUtils.getTime(), "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        
        try {
            // 使用EasyExcel写入失败数据
            EasyExcel.write(response.getOutputStream(), DoorAdslImportRespVO.class)
                    .sheet("导入失败数据")
                    .doWrite(failureList);
            
            log.info("资料导入完成，结果：{}", result.get("message"));
        } catch (Exception e) {
            log.error("导出Excel文件失败", e);
            throw e;
        }
    }
    @GetMapping("/importDataStatus")
    @ApiOperation("房产导入状态")
    @Log(title = "房产管理", businessType = BusinessType.IMPORT)
    public AjaxResult importData(String uuid) throws Exception {
        return AjaxResult.success(redisCache.getCacheObject("adslimport"+uuid));
    }
    @PostMapping("/changeGuid")
    @ApiOperation("资料导入")
    @Log(title = "房产管理", businessType = BusinessType.IMPORT)
    public AjaxResult changeGuid(@RequestBody DoorAdslChangeGuidReqVO reqVO) throws Exception {
        doorAdslService.changeGuid(reqVO);
        return AjaxResult.success();
    }


    @PostMapping("/getChangeLog")
    @ApiOperation("guid修改记录")
    @Log(title = "房产管理", businessType = BusinessType.IMPORT)
    public AjaxResult getChangeLog(@RequestBody DoorAdslChangeGuidReqVO reqVO) throws Exception {
        List<DoorGuidLog> list = easyEntityQuery.queryable(DoorGuidLog.class).where(d -> d.adslId().eq(reqVO.getId())).toList();
        return AjaxResult.success(list);
    }



}
